package cc.rengu.redp.bizimpl.csmc.service.impl;

import cc.rengu.redp.bizimpl.csmc.dao.ReconSceneInfoMapper;
import cc.rengu.redp.bizimpl.csmc.dao.ReconSceneStatMapper;
import cc.rengu.redp.bizimpl.csmc.dao.ReconSysStatMapper;
import cc.rengu.redp.bizimpl.csmc.domain.ReconSceneInfo;
import cc.rengu.redp.bizimpl.csmc.domain.ReconSceneStat;
import cc.rengu.redp.bizimpl.csmc.domain.ReconSysStat;
import cc.rengu.redp.bizimpl.csmc.service.IReconSceneStatService;
import cc.rengu.redp.bizimpl.csmc.vo.ReconSceneInfoVO;
import cc.rengu.redp.bizimpl.csmc.vo.ReconSceneStatVO;
import cc.rengu.redp.bizimpl.enums.BizDataAuditStatusEnum;
import cc.rengu.redp.bizimpl.enums.BizDataStatusEnum;
import cc.rengu.redp.bizimpl.enums.PageOptFlagEnum;
import cc.rengu.redp.bizimpl.upmp.service.IUpmpSysParamService;
import cc.rengu.redp.bizimpl.upmp.vo.UpmpUserInfoVO;
import cc.rengu.redp.bizimpl.utils.CommonUtils;
import cc.rengu.redp.common.domain.QueryRequest;
import cc.rengu.redp.common.exception.RedpException;
import cc.rengu.redp.common.utils.DateUtil;
import cc.rengu.redp.common.utils.SortUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author System
 */
@DS("csmc")
@Slf4j
@Service("reconSceneStatService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class ReconSceneStatServiceImpl extends ServiceImpl<ReconSceneStatMapper, ReconSceneStat> implements IReconSceneStatService {

    @Autowired
    private ReconSysStatMapper reconSysStatMapper;
    @Autowired
    private ReconSceneInfoMapper reconSceneInfoMapper;
    @Autowired
    private IUpmpSysParamService upmpSysParamService;


    @Override
    public IPage<ReconSceneStat> findByPage(QueryRequest request, ReconSceneStat reconSceneStat) {
        LambdaQueryWrapper<ReconSceneStat> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmpty(reconSceneStat.getInstId())) {
            lambdaQueryWrapper.eq(ReconSceneStat::getInstId, reconSceneStat.getInstId());
        }
        if (!StringUtils.isEmpty(reconSceneStat.getReconSceneId())) {
            lambdaQueryWrapper.likeRight(ReconSceneStat::getReconSceneId, reconSceneStat.getReconSceneId());
        }
        if (!StringUtils.isEmpty(reconSceneStat.getReconAtHolday())){
            lambdaQueryWrapper.eq(ReconSceneStat::getReconAtHolday, reconSceneStat.getReconAtHolday());
        }
        if (!StringUtils.isEmpty(reconSceneStat.getStatus())){
            lambdaQueryWrapper.eq(ReconSceneStat::getStatus, reconSceneStat.getStatus());
        }
        if (!StringUtils.isEmpty(reconSceneStat.getAuditStatus())){
            lambdaQueryWrapper.eq(ReconSceneStat::getAuditStatus, reconSceneStat.getAuditStatus());
        }
        Page<ReconSceneStat> page = new Page<>();
        SortUtil.handlePageSort(request, page, true);
        try {
            Page<ReconSceneStat> page1 = this.page(page, lambdaQueryWrapper);
            return this.page(page, lambdaQueryWrapper);
        } catch (Exception e) {
            log.error("查询数据异常", e);
            return null;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(ReconSceneStatVO reconSceneStatVO) throws RedpException {
        String dateTime = DateUtil.formatFullTime(LocalDateTime.now(), DateUtil.FULL_TIME_WITH_MILL_SPLIT_PATTERN);
        //当前用户ID
        //String currentUser = String.valueOf(RedpUtil.getCurrentUser().getUserId());
        //获取当前登录人信息
        UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
        String currentUser = user.getInstId();
        log.info("========================", user);
        ReconSceneStat reconSceneStat = new ReconSceneStat();
        BeanUtils.copyProperties(reconSceneStatVO, reconSceneStat);
        reconSceneStat.setStatus(BizDataStatusEnum.STATUS_DRAFT.getType());
        reconSceneStat.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_ADD_PASS.getType());
        reconSceneStat.setCreateTime(dateTime);
        reconSceneStat.setAuditTime(dateTime);
        reconSceneStat.setOprId(currentUser);
        reconSceneStat.setAuditOprId(currentUser);
//        reconSceneStat.setInstId(user.getInstId());

        this.save(reconSceneStat);
        List<ReconSceneInfoVO> reconSceneInfoVOList = JSON.parseArray(reconSceneStatVO.getReconSceneInfoJson(), ReconSceneInfoVO.class);
//        List<BizTmp> bizTmps = Lists.newArrayList();
//        List<ReconSceneInfo> reconSceneInfoList = Lists.newArrayList();
//        List<ReconSysStat> reconSysStatList = Lists.newArrayList();
        for (ReconSceneInfoVO vo : reconSceneInfoVOList) {
            addFromVo(vo, reconSceneStat, dateTime, currentUser);

        }
    }

    @Override
    @Transactional(rollbackFor = RedpException.class)
    public void update(ReconSceneStatVO reconSceneStatVO) throws RedpException {
        ReconSceneStat reconSceneStat = this.baseMapper.selectById(reconSceneStatVO.getId());
       if(!StringUtils.isEmpty(reconSceneStat)){
            String dateTime = DateUtil.formatFullTime(LocalDateTime.now(), DateUtil.FULL_TIME_WITH_MILL_SPLIT_PATTERN);
           //获取当前登录人信息
           UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
           //当前用户ID
           String currentUser = user.getId();
           BeanUtils.copyProperties(reconSceneStatVO, reconSceneStat);
            reconSceneStat.setStatus(BizDataStatusEnum.STATUS_NORMAL.getType());
            reconSceneStat.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_UPD_PASS.getType());
            reconSceneStat.setUpdateTime(dateTime);
            this.updateById(reconSceneStat);
            List<ReconSceneInfoVO> reconSceneInfoVOList = JSON.parseArray(reconSceneStatVO.getReconSceneInfoJson(), ReconSceneInfoVO.class);

            ReconSceneInfo reconSceneInfoDB = new ReconSceneInfo();
            reconSceneInfoDB.setInstId(reconSceneStat.getInstId());
            reconSceneInfoDB.setReconSceneId(reconSceneStat.getReconSceneId());
            List<ReconSceneInfoVO> reconSceneInfoVOListDB = reconSceneInfoMapper.findList(reconSceneInfoDB);
            List<ReconSceneInfoVO> reconSceneInfoVOListAdd = Lists.newArrayList();
            List<ReconSceneInfoVO> reconSceneInfoVOListUpd = Lists.newArrayList();
            List<String> reconSceneInfoVOListDel = Lists.newArrayList();
            List<String> reconSceneStatVOListDel = Lists.newArrayList();
            if (!CollectionUtils.isEmpty(reconSceneInfoVOList)) {
                //获取新增、修改
                for (ReconSceneInfoVO vo : reconSceneInfoVOList) {
                    //获取新增
                    if (StringUtils.isEmpty(vo.getId())) {
                        reconSceneInfoVOListAdd.add(vo);
                    } else {
                        //获取修改
                        reconSceneInfoVOListUpd.add(vo);
                    }
                }

                //获取删除数据
                for (ReconSceneInfoVO vodb : reconSceneInfoVOListDB) {
                    boolean del = true;
                    for (ReconSceneInfoVO vo : reconSceneInfoVOList) {
                        if (vodb.getId().equals(vo.getId())) {
                            del = false;
                        }
                    }
                    if (del) {
                        reconSceneInfoVOListDel.add(vodb.getId());
                        reconSceneStatVOListDel.add(vodb.getReconSysStatId());
                    }
                }
            }
            addListFromVo(reconSceneInfoVOListAdd, reconSceneStat, dateTime, currentUser);
            updListFromVo(reconSceneInfoVOListUpd, reconSceneStat, dateTime, currentUser);
            if (!CollectionUtils.isEmpty(reconSceneInfoVOListDel)) {
                this.reconSceneInfoMapper.deleteBatchIds(reconSceneInfoVOListDel);
            }
            if (!CollectionUtils.isEmpty(reconSceneStatVOListDel)) {
                this.reconSysStatMapper.deleteBatchIds(reconSceneStatVOListDel);
            }

        }
    }

    /**
     * 保存新增数据列表
     *
     * @param reconSceneInfoVOListAdd
     * @param reconSceneStat
     * @param dateTime
     * @param currentUser
     */
    public void addListFromVo(List<ReconSceneInfoVO> reconSceneInfoVOListAdd, ReconSceneStat reconSceneStat, String dateTime, String currentUser) {
        for (ReconSceneInfoVO vo : reconSceneInfoVOListAdd) {
            //新增
            addFromVo(vo, reconSceneStat, dateTime, currentUser);
        }
    }

    /**
     * 保存修改数据列表
     *
     * @param reconSceneInfoVOListUpd
     * @param reconSceneStat
     * @param dateTime
     * @param currentUser
     */
    public void updListFromVo(List<ReconSceneInfoVO> reconSceneInfoVOListUpd, ReconSceneStat reconSceneStat, String dateTime, String currentUser) {
        for (ReconSceneInfoVO vo : reconSceneInfoVOListUpd) {
            //修改
            updFromVo(vo, reconSceneStat, dateTime, currentUser);
        }
    }

    /**
     * 新增
     *
     * @param vo
     * @param reconSceneStat
     * @param dateTime
     * @param currentUser
     */
    public void addFromVo(ReconSceneInfoVO vo, ReconSceneStat reconSceneStat, String dateTime, String currentUser) {
        //新增
        ReconSceneInfo reconSceneInfo = new ReconSceneInfo();
        BeanUtils.copyProperties(vo, reconSceneInfo);
        reconSceneInfo.setReconSceneId(reconSceneStat.getReconSceneId());
        reconSceneInfo.setReconSceneDesc(vo.getReconSysSceneDesc());
        reconSceneInfo.setStatus(reconSceneStat.getStatus());
        reconSceneInfo.setAuditStatus(reconSceneStat.getAuditStatus());
        reconSceneInfo.setCreateTime(dateTime);
        reconSceneInfo.setAuditTime(dateTime);
        reconSceneInfo.setOprId(currentUser);
        reconSceneInfo.setAuditOprId(currentUser);
        reconSceneInfo.setUpdateTime(dateTime);

        ReconSysStat reconSysStat = new ReconSysStat();
        BeanUtils.copyProperties(vo, reconSysStat);
        reconSysStat.setId(vo.getReconSysStatId());

        reconSysStat.setStatus(reconSceneStat.getStatus());
        reconSysStat.setAuditStatus(reconSceneStat.getAuditStatus());
        reconSysStat.setCreateTime(dateTime);
        reconSysStat.setAuditTime(dateTime);
        reconSysStat.setOprId(currentUser);
        reconSysStat.setAuditOprId(currentUser);
        reconSysStat.setUpdateTime(dateTime);

        reconSceneInfoMapper.insert(reconSceneInfo);
        reconSysStatMapper.insert(reconSysStat);
        /** 目前不需要审核，后续考虑是否需要放正式表、临时表 **/
    }

    /**
     * 修改
     *
     * @param vo
     * @param reconSceneStat
     * @param dateTime
     * @param currentUser
     */
    public void updFromVo(ReconSceneInfoVO vo, ReconSceneStat reconSceneStat, String dateTime, String currentUser) {

//        ReconSceneInfo reconSceneInfo = reconSceneInfoMapper.selectById(vo.getId());
        LambdaQueryWrapper<ReconSceneInfo> Wrapper = new LambdaQueryWrapper<>();
        Wrapper.eq(ReconSceneInfo::getInstId,vo.getInstId());
        Wrapper.eq(ReconSceneInfo::getReconSysId,vo.getReconSysId());
        Wrapper.eq(ReconSceneInfo::getReconSceneId,vo.getReconSceneId());
        ReconSceneInfo reconSceneInfo = reconSceneInfoMapper.selectOne(Wrapper);
        BeanUtils.copyProperties(vo, reconSceneInfo);
        reconSceneInfo.setReconSceneDesc(vo.getReconSysSceneDesc());
        reconSceneInfo.setStatus(reconSceneStat.getStatus());
        reconSceneInfo.setAuditStatus(reconSceneStat.getAuditStatus());
        reconSceneInfo.setUpdateTime(dateTime);
//        reconSceneInfoMapper.updateById(reconSceneInfo);
        reconSceneInfoMapper.update(reconSceneInfo,Wrapper);

        if (!StringUtils.isEmpty(vo.getReconSysStatId())) {
            LambdaQueryWrapper<ReconSysStat> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ReconSysStat::getInstId,vo.getInstId());
            queryWrapper.eq(ReconSysStat::getReconSysId,vo.getReconSysId());
            ReconSysStat reconSysStat = reconSysStatMapper.selectOne(queryWrapper);
//            ReconSysStat reconSysStat = reconSysStatMapper.selectOne(queryWrapper);
            if (ObjectUtils.isEmpty(reconSysStat)) {
                //新增
                reconSysStat = new ReconSysStat();
                BeanUtils.copyProperties(vo, reconSceneStat);
                reconSysStat.setId(vo.getReconSysStatId());
                reconSysStat.setReconSysId(vo.getReconSysId());

                reconSysStat.setStatus(reconSceneStat.getStatus());
                reconSysStat.setAuditStatus(reconSceneStat.getAuditStatus());
                reconSysStat.setCreateTime(dateTime);
                reconSysStat.setAuditTime(dateTime);
                reconSysStat.setOprId(currentUser);
                reconSysStat.setAuditOprId(currentUser);
                reconSysStatMapper.insert(reconSysStat);
            } else {

                BeanUtils.copyProperties(vo, reconSysStat);
                reconSysStat.setStatus(reconSceneStat.getStatus());
                reconSysStat.setAuditStatus(reconSceneStat.getAuditStatus());
                reconSysStat.setUpdateTime(dateTime);
                reconSysStatMapper.updateById(reconSysStat);
            }

        } else {
            ReconSysStat reconSysStat = new ReconSysStat();
            BeanUtils.copyProperties(vo, reconSysStat);
            reconSysStat.setId(vo.getReconSysStatId());

            reconSysStat.setStatus(reconSceneStat.getStatus());
            reconSysStat.setAuditStatus(reconSceneStat.getAuditStatus());
            reconSysStat.setCreateTime(dateTime);
            reconSysStat.setAuditTime(dateTime);
            reconSysStat.setOprId(currentUser);
            reconSysStat.setAuditOprId(currentUser);
            reconSysStatMapper.insert(reconSysStat);
        }
        /** 目前不需要审核，后续考虑是否需要放正式表、临时表 **/
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeStatus(String id, String optFlag) throws RedpException {
        ReconSceneStat reconSceneStat = this.baseMapper.selectById(id);
        if (!ObjectUtils.isEmpty(reconSceneStat)) {
            String status = "";
            String auditStatus = "";
            if (PageOptFlagEnum.OPT_FLAG_USE.getType().equals(optFlag)) {
                if (!BizDataStatusEnum.STATUS_STOPED.getType().equals(reconSceneStat.getStatus())) {
                    log.error("当前记录已停用或注销，不能停用");
                    throw new RedpException("当前记录非停用状态，不能启用");
                }
                status = BizDataStatusEnum.STATUS_NORMAL.getType();
                auditStatus = BizDataAuditStatusEnum.AUDIT_STATUS_USE_PASS.getType();
            } else if (PageOptFlagEnum.OPT_FLAG_STOP.getType().equals(optFlag)) {
                if (BizDataStatusEnum.STATUS_STOPED.getType().equals(reconSceneStat.getStatus())
                        || BizDataStatusEnum.STATUS_CANCELED.getType().equals(reconSceneStat.getStatus())) {
                    log.error("当前记录已停用或注销，不能停用");
                    throw new RedpException("当前记录已停用或注销，不能停用");
                }

                status = BizDataStatusEnum.STATUS_STOPED.getType();
                auditStatus = BizDataAuditStatusEnum.AUDIT_STATUS_STOP_PASS.getType();
            } else if (PageOptFlagEnum.OPT_FLAG_CANCEL.getType().equals(optFlag)) {
                if (BizDataStatusEnum.STATUS_CANCELED.getType().equals(reconSceneStat.getStatus())) {
                    log.error("当前记录注销状态，不能注销");
                    throw new RedpException("当前记录注销状态，不能注销");
                }
                status = BizDataStatusEnum.STATUS_CANCELED.getType();
                auditStatus = BizDataAuditStatusEnum.AUDIT_STATUS_CANCEL_PASS.getType();
            }
            String dateTime = DateUtil.formatFullTime(LocalDateTime.now(), DateUtil.FULL_TIME_WITH_MILL_SPLIT_PATTERN);
//            //当前用户ID
//            String currentUser = String.valueOf(RedpUtil.getCurrentUser().getUserId());
            //获取当前登录人信息
            UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
            String currentUser = user.getInstId();
            reconSceneStat.setStatus(status);
            reconSceneStat.setAuditStatus(auditStatus);
            reconSceneStat.setUpdateTime(dateTime);
            reconSceneStat.setAuditOprId(currentUser);
            reconSceneStat.setAuditTime(dateTime);
            this.updateById(reconSceneStat);

            ReconSceneInfo reconSceneInfo = new ReconSceneInfo();
            reconSceneInfo.setInstId(reconSceneStat.getInstId());
            reconSceneInfo.setReconSceneId(reconSceneStat.getReconSceneId());
            List<ReconSceneInfoVO> list = reconSceneInfoMapper.findList(reconSceneInfo);
            for (ReconSceneInfoVO vo : list) {
                BeanUtils.copyProperties(vo, reconSceneInfo);
                reconSceneInfo.setStatus(status);
                reconSceneInfo.setAuditStatus(auditStatus);
                reconSceneInfo.setUpdateTime(dateTime);
                reconSceneInfo.setAuditOprId(currentUser);
                reconSceneInfo.setAuditTime(dateTime);
                reconSceneInfoMapper.updateByReconSceneId(reconSceneInfo);

                ReconSysStat reconSysStat = new ReconSysStat();
                BeanUtils.copyProperties(vo, reconSysStat);
                reconSysStat.setStatus(status);
                reconSysStat.setAuditStatus(auditStatus);
                reconSysStat.setUpdateTime(dateTime);
                reconSysStat.setAuditOprId(currentUser);
                reconSysStat.setAuditTime(dateTime);
                reconSysStatMapper.updateByReconSysId(reconSysStat);
            }

            log.info("对账场景管理[对账场景标识{}]状态变更成功", reconSceneStat.getReconSceneId());
        } else {
            log.error("当前记录已停用或注销，不能停用");
            throw new RedpException("当前记录非停用状态，不能启用");
        }
    }

    @Override
    public ReconSceneStat ByReconSceneId(String instId, String  reconSceneId) {
        LambdaQueryWrapper<ReconSceneStat> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(ReconSceneStat::getInstId, instId)
                            .eq(ReconSceneStat::getReconSceneId, reconSceneId)
                            .eq(ReconSceneStat::getStatus, "01");
        ReconSceneStat reconSceneStat = this.getOne(lambdaQueryWrapper);
        return reconSceneStat;
    }
}
